home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr13 / afv95.zip / MAIN.CPP < prev    next >
C/C++ Source or Header  |  1995-02-13  |  10KB  |  666 lines

  1. /*
  2. AFVIEW.EXE - a browser for Invention Factory's ALLFILE.DIR text file.
  3.  
  4. This program was written by Chris Sokol.  It is worth nothing, and anyone can
  5. do anything with it that they would like to.
  6. */
  7.  
  8. #include <bios.h>
  9. #include <ctype.h>
  10. #include <dos.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "index.h"
  15. #include "kbd.h"
  16. #include "sort.h"
  17. #include "video.h"
  18.  
  19. static void        AFV();
  20. static void        ArgsInit(int argc, char **argv);
  21. static void        BotFile();
  22. static void        BotScr();
  23. static int        ContainsSearch(int line);
  24. static void        CursDn();
  25. static void        CursUp();
  26. static uint        DosAlloc(uint pcnt);
  27. static void        DosFree(uint para);
  28. static int        LineCmp(const void *p1, const void *p2);
  29. static void        LoadSubDir(uint topic);
  30. static void        MkLine(uint base, uint l, char *text);
  31. static void        MkMaster();
  32. static void        PageDn();
  33. static void        PageUp();
  34. static void        ProcKey();
  35. static void        Refresh();
  36. static void        SearchNext();
  37. static void        Sort();
  38. static void        TopFile();
  39. static void        TopScr();
  40. static void        Usage();
  41. static void        ViewMaster();
  42. static void        ViewSubDir(uint topic);
  43.  
  44. static FILE        *afdir;
  45. static uint        curoff;
  46. static ulong    *lineoffs;
  47. static uint        *lines;
  48. static uint        master;
  49. static uint        nlines;
  50. static uint        pagesz;
  51. static uint        savcur;
  52. static uint        savtop;
  53. static char        search[81];
  54. static int        showhelp;
  55. static int        sortkey;
  56. static int        startdir;
  57. static uint        subdir;
  58. static uint        topline;
  59. static int        running;
  60. static int        use8x8;
  61. static int        vwmaster;
  62.  
  63. void    AFV()
  64. {
  65.     running    = 1;
  66.  
  67.     if (startdir >= 1 && startdir <= TopicCnt())
  68.         ViewSubDir(startdir - 1);
  69.     else 
  70.         ViewMaster();
  71.  
  72.     while (running)
  73.         ProcKey();
  74. }
  75.  
  76. void    ArgsInit(int argc, char **argv)
  77. {
  78.     int    a;
  79.  
  80.     startdir    = -1;
  81.     use8x8    = 0;
  82.  
  83.     for (a = 1 ; a < argc ; a++)
  84.         if (argv[a][0] == '-')
  85.             {
  86.             switch (argv[a][1])
  87.                 {
  88.                 case '8':
  89.                     use8x8 = 1;
  90.                     break;
  91.  
  92.                 default:
  93.                     Usage();
  94.                 }
  95.             }
  96.         else if (isdigit(argv[a][0]))
  97.             startdir = atoi(argv[a]);
  98.         else 
  99.             Usage();
  100. }
  101.  
  102. void    BotFile()
  103. {
  104.     if (nlines < pagesz)
  105.         {
  106.         topline = 0;
  107.         curoff = nlines - 1;
  108.         }
  109.     else
  110.         {
  111.         topline = nlines - pagesz;
  112.         curoff = pagesz - 1;
  113.         }
  114.  
  115.     Refresh();
  116. }
  117.  
  118. void    BotScr()
  119. {
  120.     if (nlines < pagesz)
  121.         curoff = nlines - 1;
  122.     else
  123.         curoff = pagesz - 1;
  124.  
  125.     Refresh();
  126. }
  127.  
  128. int    ContainsSearch(int line)
  129. {
  130.     uint    base;
  131.     char    *text;
  132.     int    len, x;
  133.  
  134.     base    = vwmaster ? master : subdir;
  135.     text    = (char*)MK_FP(base + line * 5, 0);
  136.     len    = strlen(search);
  137.  
  138.     for (x = 0 ; x < 80 ; x++)
  139.         if (!memicmp(text + x, search, len))
  140.             return 1;
  141.  
  142.     return 0;
  143. }
  144.  
  145. void    CursDn()
  146. {
  147.     if (topline + curoff + 1 < nlines)
  148.         if (curoff + 1 < pagesz)
  149.             curoff++;
  150.         else
  151.             topline++;
  152.  
  153.     Refresh();
  154. }
  155.  
  156. void    CursUp()
  157. {
  158.     if (curoff)
  159.         curoff--;
  160.     else if (topline)
  161.         topline--;
  162.  
  163.     Refresh();
  164. }
  165.  
  166. uint    DosAlloc(uint pcnt)
  167. {
  168.     uchar    *tmp[4];
  169.     REGS    r;
  170.  
  171.     tmp[0] = new uchar[32768];
  172.     tmp[1] = new uchar[32768];
  173.     tmp[2] = new uchar[32768];
  174.     tmp[3] = new uchar[32768];
  175.  
  176.     r.h.ah = 0x48;
  177.     r.x.bx = pcnt;
  178.     intdos(&r, &r);
  179.  
  180.     delete tmp[3];
  181.     delete tmp[2];
  182.     delete tmp[1];
  183.     delete tmp[0];
  184.  
  185.     if (r.x.cflag)
  186.         return 0;
  187.     else
  188.         return r.x.ax;
  189. }
  190.  
  191. void    DosFree(uint para)
  192. {
  193.     SREGS    s;
  194.     REGS    r;
  195.  
  196.     segread(&s);
  197.     s.es = para;
  198.  
  199.     r.h.ah = 0x49;
  200.     intdosx(&r, &r, &s);
  201. }
  202.  
  203. int    LineCmp(const void *p1, const void *p2)
  204. {
  205.     uint    *u1 = (uint*)p1, *u2 = (uint*)p2;
  206.     char    *f1, *f2;
  207.  
  208.     f1 = (char*)MK_FP(subdir + (*u1) * 5, 0);
  209.     f2 = (char*)MK_FP(subdir + (*u2) * 5, 0);
  210.  
  211.     if (sortkey == SKdate)
  212.         {
  213.         int    m1, m2, d1, d2, y1, y2;
  214.  
  215.         m1 = atoi(f1 + 23);
  216.         d1 = atoi(f1 + 26);
  217.         y1 = atoi(f1 + 29);
  218.         m2 = atoi(f2 + 23);
  219.         d2 = atoi(f2 + 26);
  220.         y2 = atoi(f2 + 29);
  221.  
  222.         if (y1 < y2)
  223.             return -1;
  224.         else if (y1 > y2)
  225.             return 1;
  226.         else if (m1 < m2)
  227.             return -1;
  228.         else if (m1 > m2)
  229.             return 1;
  230.         else if (d1 < d2)
  231.             return -1;
  232.         else if (d1 > d2)
  233.             return 1;
  234.         else
  235.             return stricmp(f1, f2);
  236.         }
  237.     else if (sortkey == SKname)
  238.         return stricmp(f1, f2);
  239.     else if (sortkey == SKsize)
  240.         {
  241.         char    *sz1, *sz2;
  242.         long    s1, s2;
  243.  
  244.         for (sz1 = f1 + 12 ; isspace(*sz1) ; sz1++)
  245.             ;
  246.  
  247.         for (sz2 = f2 + 12 ; isspace(*sz2) ; sz2++)
  248.             ;
  249.  
  250.         s1 = atol(sz1);
  251.         s2 = atol(sz2);
  252.  
  253.         if (s1 < s2)
  254.             return -1;
  255.         else if (s1 > s2)
  256.             return 1;
  257.         else
  258.             return stricmp(f1, f2);
  259.         }
  260.     else
  261.         return 0;
  262. }
  263.  
  264. void    LoadSubDir(uint t)
  265. {
  266.     char    line[100];
  267.  
  268.     fseek(afdir, Offset(t), 0);
  269.     nlines = 0;
  270.  
  271.     memcpy(line, MK_FP(master + (t + 2) * 5, 0), 80);
  272.     line[80] = 0;
  273.     lineoffs[nlines] = 0xffffffff;
  274.     MkLine(subdir, nlines++, line);
  275.  
  276.     memset(line, 205, 80);
  277.     line[80] = 0;
  278.     lineoffs[nlines] = 0xffffffff;
  279.     MkLine(subdir, nlines++, line);
  280.  
  281.     while (nlines < 3000)
  282.         {
  283.         char    *p;
  284.         int    tag;
  285.  
  286.         lineoffs[nlines] = ftell(afdir);
  287.  
  288.         fgets(line, sizeof(line), afdir);
  289.  
  290.         if (feof(afdir))
  291.             break;
  292.  
  293.         p = strchr(line, 0);
  294.  
  295.         while (p > line && isspace(*(p - 1)))
  296.             *--p = 0;
  297.  
  298.         if (!line[0] || line[0] == '╒')
  299.             break;
  300.  
  301.         MkLine(subdir, nlines, line);
  302.  
  303.         nlines++;
  304.         }
  305. }
  306.  
  307. int    main(int argc, char *argv[])
  308. {
  309.     ArgsInit(argc, argv);
  310.  
  311.     OpenIndex();
  312.  
  313.     afdir = fopen("allfile.dir", "r+b");
  314.  
  315.     if (!afdir)
  316.         {
  317.         fprintf(stderr, "Unable to open ALLFILE.DIR\n");
  318.         return 1;
  319.         }
  320.  
  321.     MkMaster();
  322.  
  323.     subdir = DosAlloc(15000);
  324.  
  325.     if (!subdir)
  326.         {
  327.         DosFree(master);
  328.         fclose(afdir);
  329.  
  330.         fprintf(stderr, "Unable to allocate enough memory\n");
  331.         return 1;
  332.         }
  333.  
  334.     lineoffs = new ulong[3000];
  335.  
  336.     VidInit(use8x8);
  337.  
  338.     VidTopLine("AFView - ALLFILEViewer.  For use with Invention Factory ALLFILE.DIR");
  339.     VidBotLine("Written by Chris Sokol 2/95.");
  340.  
  341.     pagesz = VidRows() - 2;
  342.  
  343.     AFV();
  344.  
  345.     VidTerm();
  346.  
  347.     delete lineoffs;
  348.     DosFree(subdir);
  349.     DosFree(master);
  350.  
  351.     return 0;
  352. }
  353.  
  354. void    MkLine(uint base, uint l, char *text)
  355. {
  356.     char    *p;
  357.     int    len;
  358.  
  359.     p = (char*)MK_FP(base + l * 5, 0);
  360.  
  361.     len = strlen(text);
  362.  
  363.     if (len > 80)
  364.         len = 80;
  365.  
  366.     memset(p, ' ', 80);
  367.     memcpy(p, text, len);
  368. }
  369.  
  370. void    MkMaster()
  371. {
  372.     int    t;
  373.     char    line[81];
  374.  
  375.     master = DosAlloc((TopicCnt() + 2) * 5);
  376.  
  377.     MkLine(master, 0, "Description                                                Files      Bytes");
  378.     MkLine(master, 1, "═══════════                                                ═════      ═════");
  379.  
  380.     for (t = 0 ; t < TopicCnt() ; t++)
  381.         {
  382.         sprintf(line, "%-53s %10ld %10ld", Descr(t), FilCnt(t), BytCnt(t));
  383.  
  384.         MkLine(master, t + 2, line);
  385.         }
  386. }
  387.  
  388. void    *operator new(uint size)
  389. {
  390.     void    *m;
  391.  
  392.     m = calloc(1, size);
  393.  
  394.     if (!m)
  395.         {
  396.         REGS    r;
  397.  
  398.         r.x.ax = 0x0003;
  399.         int86(0x10, &r, &r);
  400.  
  401.         fprintf(stderr, "Out of memory!\n");
  402.         exit(1);
  403.         }
  404.  
  405.     return m;
  406. }
  407.  
  408. void    PageDn()
  409. {
  410.     if (topline + pagesz * 2 <= nlines)
  411.         topline += pagesz;
  412.     else if (topline + pagesz < nlines)
  413.         topline = nlines - pagesz;
  414.     else
  415.         {
  416.         BotFile();
  417.         return;
  418.         }
  419.  
  420.     Refresh();
  421. }
  422.  
  423. void    PageUp()
  424. {
  425.     if (topline)
  426.         if (topline >= pagesz)
  427.             topline -= pagesz;
  428.         else
  429.             topline = 0;
  430.     else
  431.         curoff = 0;
  432.  
  433.     Refresh();
  434. }
  435.  
  436. void    ProcKey()
  437. {
  438.     uint    k;
  439.  
  440.     k = bioskey(0);
  441.  
  442.     if (k & 0x00ff)
  443.         k &= 0x00ff;
  444.  
  445.     VidBotLine("Written by Chris Sokol 3/95.");
  446.  
  447.     if (showhelp)
  448.         {
  449.         Refresh();
  450.         showhelp = 0;
  451.         }
  452.     else if (k == 27)
  453.         running = 0;
  454.     else if (k == KB_CURS_UP)
  455.         CursUp();
  456.     else if (k == KB_CURS_DN)
  457.         CursDn();
  458.     else if (k == KB_PAGE_UP)
  459.         PageUp();
  460.     else if (k == KB_PAGE_DN)
  461.         PageDn();
  462.     else if (k == KB_HOME)
  463.         TopScr();
  464.     else if (k == KB_END)
  465.         BotScr();
  466.     else if (k == KB_CTL_HOME)
  467.         TopFile();
  468.     else if (k == KB_CTL_END)
  469.         BotFile();
  470.     else if (k == '\n' || k == '\r')
  471.         if (vwmaster)
  472.             {
  473.             if (topline + curoff >= 2)
  474.                 {
  475.                 savcur = curoff;
  476.                 savtop = topline;
  477.  
  478.                 ViewSubDir(topline + curoff - 2);
  479.                 }
  480.             }
  481.         else
  482.             ViewMaster();
  483.     else if (k == KB_F1)
  484.         {
  485.         VidHelp();
  486.         showhelp = 1;
  487.         }
  488.     else if (k == KB_F5)
  489.         {
  490.         if (VidInput("Enter search text:", search, 80))
  491.             {
  492.             VidSearch(search);
  493.             Refresh();
  494.  
  495.             if (search[0])
  496.                 if (VidFound())
  497.                     {
  498.                     curoff = FndLine();
  499.                     Refresh();
  500.                     }
  501.                 else 
  502.                     SearchNext();
  503.             }
  504.         }
  505.     else if (k == KB_SHF_F5)
  506.         if (search[0])
  507.             SearchNext();
  508.         else
  509.             VidBotLine("Nothing to search for!");
  510.     else if (k == KB_ALT_S)
  511.         Sort();
  512. }
  513.  
  514. void    Refresh()
  515. {
  516.     VidCursor(curoff);
  517.     VidRefresh(topline);
  518. }
  519.  
  520. void    SearchNext()
  521. {
  522.     if (topline + pagesz * 2 <= nlines)
  523.         {
  524.         topline += pagesz;
  525.  
  526.         while (topline + pagesz < nlines)
  527.             if (ContainsSearch(topline))
  528.                 break;
  529.             else
  530.                 topline++;
  531.  
  532.         Refresh();
  533.  
  534.         if (VidFound())
  535.             {
  536.             curoff = FndLine();
  537.             Refresh();
  538.             }
  539.         }
  540. }
  541.  
  542. void    Sort()
  543. {
  544.     uint    x;
  545.     FILE    *f;
  546.  
  547.     VidBotLine("Sort by (D)ate, (N)ame, (S)ize.");
  548.  
  549.     while (1)
  550.         {
  551.         uint    k;
  552.  
  553.         k = bioskey(0) & 0x00ff;
  554.  
  555.         if (k == 27)
  556.             {
  557.             VidBotLine("Sort aborted.");
  558.             return;
  559.             }
  560.         else if (k == 'd' || k == 'D')
  561.             {
  562.             sortkey = SKdate;
  563.             break;
  564.             }
  565.         else if (k == 'n' || k == 'N')
  566.             {
  567.             sortkey = SKname;
  568.             break;
  569.             }
  570.         else if (k == 's' || k == 'S')
  571.             {
  572.             sortkey = SKsize;
  573.             break;
  574.             }
  575.         }
  576.  
  577.     VidBotLine("Sorting...");
  578.  
  579.     lines = new uint[nlines];
  580.  
  581.     for (x = 0 ; x < nlines - 2 ; x++)
  582.         lines[x] = x + 2;
  583.  
  584.     qsort(lines, nlines - 2, sizeof(uint), LineCmp);
  585.  
  586.     f = fopen("temp.tmp", "wb");
  587.  
  588.     for (x = 0 ; x < nlines - 2 ; x++)
  589.         {
  590.         char    *l;
  591.  
  592.         l = (char*)MK_FP(subdir + lines[x] * 5, 0);
  593.  
  594.         fwrite(l, 1, 80, f);
  595.         }
  596.  
  597.     fclose(f);
  598.  
  599.     f = fopen("temp.tmp", "rb");
  600.  
  601.     for (x = 2 ; x < nlines ; x++)
  602.         {
  603.         char    *l;
  604.  
  605.         l = (char*)MK_FP(subdir + x * 5, 0);
  606.  
  607.         fread(l, 1, 80, f);
  608.         }
  609.  
  610.     fclose(f);
  611.  
  612.     delete lines;
  613.  
  614.     VidBotLine("Sort completed");
  615.  
  616.     Refresh();
  617. }
  618.  
  619. void    TopFile()
  620. {
  621.     curoff = 0;
  622.     topline = 0;
  623.  
  624.     Refresh();
  625. }
  626.  
  627. void    TopScr()
  628. {
  629.     curoff = 0;
  630.  
  631.     Refresh();
  632. }
  633.  
  634. void    Usage()
  635. {
  636.     fprintf(stderr, "AFVIEW [options] [dir#]\n");
  637.     fprintf(stderr, "\t-8\tUse 8x8 font (EGA/VGA)\n");
  638.  
  639.     exit(1);
  640. }
  641.  
  642. void    ViewMaster()
  643. {
  644.     curoff    = savcur;
  645.     nlines    = TopicCnt() + 2;
  646.     topline    = savtop;
  647.     vwmaster    = 1;
  648.  
  649.     VidDefData(master, nlines);
  650.  
  651.     Refresh();
  652. }
  653.  
  654. void    ViewSubDir(uint t)
  655. {
  656.     LoadSubDir(t);
  657.  
  658.     curoff    = 0;
  659.     topline    = 0;
  660.     vwmaster    = 0;
  661.  
  662.     VidDefData(subdir, nlines);
  663.  
  664.     Refresh();
  665. }
  666.